package orm

/**
 * 代理
 * 嵌入到持久化对象中
 * 用来处理持久化对象和模型之间的调用，反转两者之间的关系，从而使使用更方便
 * 使用前需要BindAgent
 */
type Agent struct {
	st SimpleTableDefiner
	m  *SimpleModel
}

func (a *Agent) Insert() error {
	if a.m == nil || a.st == nil {
		panic("调用Agent前需要先Bind")
	}
	return a.m.Insert(a.st)
}

func (a *Agent) Delete() error {
	if a.m == nil || a.st == nil {
		panic("调用Agent前需要先Bind")
	}
	_, err := a.m.Delete(a.st)
	return err
}

func (a *Agent) Update() error {
	if a.m == nil || a.st == nil {
		panic("调用Agent前需要先Bind")
	}
	_, err := a.m.Update(a.st)
	return err
}

func (a *Agent) Get() error {
	if a.m == nil || a.st == nil {
		panic("调用Agent前需要先Bind")
	}
	return a.m.Load(a.st)
}

func (a *Agent) Select(cond, order string, argv ...interface{}) (interface{}, error) {
	if a.m == nil || a.st == nil {
		panic("调用Agent前需要先Bind")
	}
	return Base(a.m.db, a.m).Where(cond, argv).Order(order).Select()
}

type Agency interface {
	Agency() *Agent
}

func (a *Agent) Agency() *Agent {
	return a
}

var sml = make(map[DataBaseOperator]*SimpleModel)

func BindAgent(db DataBaseOperator, st SimpleTableDefiner) *Agent {
	_st, ok := st.(Agency)
	if !ok {
		panic("要绑定的SimpleTable没有实现或引用代理")
	}
	a := _st.Agency()
	if _, ok := sml[db]; !ok {
		sml[db] = Simple(db)
	}
	a.m = sml[db]
	a.st = st
	return a
}
